/*
 * BSM6.0
 *
 * Copyright 2012-2013 (C) SINODATA CO., LTD. All Rights Reserved.
 */
package com.sinodata.bsm.center.web.action.resource;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.springframework.beans.factory.annotation.Autowired;

import com.sinodata.bsm.center.bean.Condition;
import com.sinodata.bsm.center.bean.Page;
import com.sinodata.bsm.center.bean.RelationHelper;
import com.sinodata.bsm.center.bean.ResBean;
import com.sinodata.bsm.center.bean.ResTypeBean;
import com.sinodata.bsm.center.cache.RelationTypeCache;
import com.sinodata.bsm.center.cache.ResCache;
import com.sinodata.bsm.center.purview.FunctionConstants;
import com.sinodata.bsm.center.purview.UserFunctionValidate;
import com.sinodata.bsm.center.service.performance.RealTimeService;
import com.sinodata.bsm.center.service.probe.ProbeService;
import com.sinodata.bsm.center.service.relation.ResRelationService;
import com.sinodata.bsm.center.service.resource.AttributeService;
import com.sinodata.bsm.center.service.resource.ResService;
import com.sinodata.bsm.center.util.spring.SpringContextHolder;
import com.sinodata.bsm.center.util.web.Struts2Utils;
import com.sinodata.bsm.center.web.action.BaseAction;
import com.sinodata.bsm.common.constants.RelationConstants;
import com.sinodata.bsm.common.vo.Attribute;
import com.sinodata.bsm.common.vo.Probe;
import com.sinodata.bsm.common.vo.RealTimeViewConf;
import com.sinodata.bsm.common.vo.RelationType;
import com.sinodata.bsm.common.vo.Res;
import com.sinodata.bsm.common.vo.ResAttrVal;
import com.sinodata.bsm.common.vo.ResRelation;
import com.sinodata.bsm.common.vo.ResType;

/**
 * <p>
 * Description: 主要用于资源的应用查询
 * </p>
 *
 * @author fanshengchao
 * @version 1.0

 * <p>
 * History: 
 *
 * Date                     Author         Version     Description
 * ---------------------------------------------------------------------------------
 * 2012-6-21 上午10:33:45          fanshengchao        1.0         To create
 * </p>
 *
 * @since 
 * @see     
 */
public class ResQueryAction extends BaseAction<Res> {

    private Res entity;
    private Long id;
    private com.sinodata.bsm.center.bean.Page<Res> page;
    @Autowired
    private ResService resService;
    @Autowired
    private AttributeService attributeService;
    @Autowired
    private ResCache resCache;
    @Autowired
    private ProbeService probeService;
    @Autowired
    private ResRelationService resRelationService;
    @Autowired
    private RealTimeService realTimeService;

    /* (non-Javadoc)
     * @see com.sinodata.bsm.center.web.action.BaseAction#delete()
     */
    @Override
    public String delete() throws Exception {
        return null;
    }

    /* (non-Javadoc)
     * @see com.sinodata.bsm.center.web.action.BaseAction#input()
     */
    @Override
    public String input() throws Exception {
        return null;
    }

    /* (non-Javadoc)
     * @see com.sinodata.bsm.center.web.action.BaseAction#list()
     */
    @Override
    @SuppressWarnings({ "unused", "unchecked" })
    public String list() throws Exception {
        Long resId = Long.parseLong(Struts2Utils.getParameter("resId"));
        Long resTypeId = resService.get(resId).getResTypeId();
        page = new Page<Res>();
        Enumeration<String> names = Struts2Utils.getRequest().getParameterNames();
        Map<String, String> newParameter = new HashMap<String, String>();
        while (names.hasMoreElements()) {
            String name = names.nextElement();
            if (name.indexOf("FILTER") != -1) {
                String value = Struts2Utils.getRequest().getParameter(name);
                newParameter.put(name.substring(name.indexOf("FILTER") + 2), value);
            }
        }
        if (resTypeId != null) {
            newParameter.put("EQ_LresTypeId", resTypeId.toString());
        }
        newParameter.put("NOT_Lid", resId.toString());

        Condition condition = new Condition();
        condition.setWhere(newParameter);

        int pageSize = Integer.parseInt(request.getParameter("iDisplayLength"));
        int start = Integer.parseInt(request.getParameter("iDisplayStart"));
        int pageno = (start / pageSize) + 1;
        page.setPageNo(pageno);
        page.setPageSize(pageSize);

        Map<String, String> orderMap = new HashMap<String, String>();
        String order = request.getParameter("sSortDir_0");
        String col = request.getParameter("mDataProp_" + request.getParameter("iSortCol_0"));
        if (!col.equals("checkbox")) {
            orderMap.put(col, order);
        }
        page.setOrder(orderMap);
        List<Res> res = resService.findByPage(page, condition);
        JSONArray array = new JSONArray();
        for (Res r : res) {
            JSONObject json = new JSONObject();
            json.element("checkbox", "<input type='checkbox'  name='res_check'   id='res_check' value='" + r.getId() + "'>");
            json.element("id", r.getId());
            json.element("ip", r.getIp() == null ? "" : r.getIp());
            json.element("name", r.getName() == null ? "" : r.getName());
            Res parent = null;
            List<ResBean> resBeans = RelationHelper.parents(r.getId());
            if (resBeans.size() > 0) {
                parent = resBeans.get(0).res();
            }

            StringBuffer parentNameValue = new StringBuffer("");
            parentNameValue.append(parent == null ? "" : parent.getName() + "/");
            parentNameValue.append(r.getName() == null ? "" : r.getName());
            json.element("parentName", parentNameValue.toString());
            array.add(json);
        }
        JSONObject object = new JSONObject();
        object.element("iTotalRecords", page.getTotal());
        object.element("iTotalDisplayRecords", page.getTotal());
        object.element("aaData", array);
        Struts2Utils.renderText(object.toString());
        return null;
    }

    /* (non-Javadoc)
     * @see com.sinodata.bsm.center.web.action.BaseAction#prepareModel()
     */
    @Override
    protected void prepareModel() throws Exception {
        if (id == null) {
            entity = new Res();
        } else {
            entity = resService.get(id);
        }
    }

    /* (non-Javadoc)
     * @see com.sinodata.bsm.center.web.action.BaseAction#save()
     */
    @Override
    public String save() throws Exception {
        return null;
    }

    /**
     * 资源应用
     * @return
     */
    public String apply() {
        Long resId = Long.parseLong(Struts2Utils.getParameter("resId"));
        Res res = resService.get(resId);
        Struts2Utils.setRequestAttribute("res", res);
        return "apply";
    }

    public String ipChange() {
        Struts2Utils.setRequestAttribute("isSelected", Struts2Utils.getParameter("isSelected"));
        return "ipchange";
    }

    /**
     * prop变更
     * @return
     */
    @SuppressWarnings("unchecked")
    public String probeChange() {
        Struts2Utils.setRequestAttribute("isSelected", Struts2Utils.getParameter("isSelected"));
        List<Probe> probes = probeService.findAllProbe();
        Collections.sort(probes, new ProbeSort());
        Struts2Utils.setRequestAttribute("probes", probes);
        return "probechange";
    }

    /**
     * Ip变更
     * @return
     */
    public String resIpChange() {
        String ipValue = Struts2Utils.getParameter("ipValue");
        String[] paramerter = ipValue.split("[@]");
        int tempIndex = Integer.parseInt(paramerter[0]);
        String relationFlag = paramerter[3];
        List<Long> resIds = new ArrayList<Long>();
        String newIp = "";

        StringBuffer privaligeAppend = new StringBuffer("当前资源：");
        Boolean hasExitPrivalige = true;
        if (tempIndex == 1) {
            newIp = paramerter[1];
            String[] resIdValue = paramerter[2].split("[,]");

            for (int i = 0; i < resIdValue.length; i++) {
                Long resId = Long.parseLong(resIdValue[i]);
                //权限认证
                if (!UserFunctionValidate.resFunctionValidate(resId, FunctionConstants.EDIT_RES)) {
                    privaligeAppend.append(i == (resIdValue.length - 1) ? resCache.get(resId).getName() : resCache.get(resId).getName() + ",");
                    hasExitPrivalige = false;
                }

                resIds.add(resId);
                if (relationFlag.equals("true")) { //按组成关系变更
                    //和当前资源有父子关系的进行变更
                    List<ResBean> beans = RelationHelper.toRec(Long.parseLong(resIdValue[i]), RelationConstants.FORM);
                    for (ResBean bean : beans) {
                        resIds.add(bean.res().getId());
                    }
                }
            }

        } else { //更新指定IP的资源IP
            newIp = paramerter[1];
            String changeIp = paramerter[2];
            List<Res> res = resCache.findAll();
            for (int i = 0; i < res.size(); i++) {
                Res r = res.get(i);
                if (r.getIp().equals(changeIp)) {
                    resIds.add(r.getId());
                }
            }
        }

        if (hasExitPrivalige) {
            resService.changeResIP(resIds, newIp);
        }
        JSONObject object = new JSONObject();
        object.element("hasExitPrivalige", hasExitPrivalige);
        object.element("privaligeVlidateResult", privaligeAppend.toString() + "没有编辑权限,不可进行IP变更");
        Struts2Utils.renderJson(object);
        return null;
    }

    public String resProbeChange() {
        String ipValue = Struts2Utils.getParameter("probeValue");
        String[] paramerter = ipValue.split("[@]");
        int tempIndex = Integer.parseInt(paramerter[0]);
        List<Long> resIds = new ArrayList<Long>();
        Long newProbeId = Long.parseLong(paramerter[1]);
        String relationFlag = paramerter[3];
        JSONObject validateOb = new JSONObject();
        boolean flag = true;
        if (tempIndex == 1) {
            String[] resIdValue = paramerter[2].split("[,]");
            for (int i = 0; i < resIdValue.length; i++) {
                Long resId = Long.parseLong(resIdValue[i]);

                if (!UserFunctionValidate.resFunctionValidate(resId, FunctionConstants.EDIT_RES)) {
                    validateOb.element("flag", false);
                    validateOb.element("info", "第" + (i + 1) + "个资源无编辑权限，不能进行probe变更");
                    break;
                }

                if (resService.get(resId) == null) {
                    validateOb.element("flag", false);
                    validateOb.element("info", "第" + (i + 1) + "个资源已经删除，不能进行probe变更");
                    break;
                }

                List<ResRelation> relList = resRelationService.getResRelationsOfRes(resId);
                //与父子源是组成关系的将不变更
                for (int r = 0; relList != null && r < relList.size(); r++) {
                    ResRelation relation = relList.get(r);
                    if (relation.getEndId().equals(Long.parseLong(resIdValue[i])) && relation.getRelationTypeId().equals(RelationConstants.FORM)) {
                        validateOb.element("flag", false);
                        validateOb.element("info", "第" + (i + 1) + "个资源不能进行probe变更,与父资源是组成关系。");
                        flag = false;
                        break;
                    }
                }

                if (flag == false) {
                    break;
                }

                resIds.add(resId);
                if (relationFlag.equals("true")) { //按组成关系变更
                    List<ResBean> beans = RelationHelper.toRec(resId, RelationConstants.FORM);
                    for (ResBean bean : beans) {
                        resIds.add(bean.res().getId());
                    }
                }
            }

        } else {
            String currentProbe = paramerter[2];
            List<Res> res = resCache.findAll();
            for (int i = 0; i < res.size(); i++) {
                Res r = res.get(i);
                if (r.getProbeId().longValue() == Long.parseLong(currentProbe)) {
                    resIds.add(r.getId());
                }
            }
        }

        if (flag) {
            resService.changeResProbeId(resIds, newProbeId);
        }
        Struts2Utils.renderJson(validateOb);
        return null;
    }

    public String view() {
        entity = resService.get(id);
        String pId = request.getParameter("pId");
        String viewId = request.getParameter("viewId");
        Struts2Utils.setRequestAttribute("id", id);
        RealTimeViewConf realConf = realTimeService.findRealTimeView(id);
        if (realConf == null) {
            request.setAttribute("hasRealConf", false);
        } else {
            request.setAttribute("hasRealConf", true);
        }
        String pageConf = realTimeService.findPageByResType(entity.getResTypeId());
        if (pageConf == null) {
            request.setAttribute("hasCombineConf", false);
        } else {
            request.setAttribute("hasCombineConf", true);
        }
        request.setAttribute("res", entity);
        request.setAttribute("pId", pId);
        request.setAttribute("viewId", viewId);
        return "viewtop";
    }

    public String viewres() {
        Struts2Utils.setRequestAttribute("resId", id);
        String pId = request.getParameter("pId");
        String viewId = request.getParameter("viewId");

        boolean hasPrivilege = UserFunctionValidate.resFunctionValidate(id, FunctionConstants.EDIT_RES);
        Struts2Utils.setRequestAttribute("hasEditResPrivilege", hasPrivilege);
        ResRelation resRelation = null;
        if (pId != null && !pId.equals("0") && !pId.equals("")) {
            List<ResRelation> relList = resRelationService.getResRelationsOfRes(id);
            for (ResRelation rel : relList) {
                if (rel.getStartId().longValue() == Long.parseLong(pId) && rel.getEndId().longValue() == id.longValue()) {
                    resRelation = rel;
                    break;
                }
            }
        }
        if (resRelation != null) {
            RelationType reltype = SpringContextHolder.getBean(RelationTypeCache.class).get(resRelation.getRelationTypeId());
            request.setAttribute("parentRes", resService.get(resRelation.getStartId()));
        }

        request.setAttribute("viewId", viewId);
        return "view";
    }

    public String findResValue() {
        ResBean bean = ResBean.get(id);
        List results = new ArrayList();
        results.add(bean.res());
        results.add(bean.type().resType());
        List<Attribute> attributes = new ArrayList<Attribute>();
        attributes.addAll(bean.type().attributes());
        //用户自定义属性
        List<Attribute> definedAttribute = attributeService.findAttributeByResId(id);
        if (definedAttribute != null) {
            attributes.addAll(definedAttribute);
        }

        List<JSONObject> attVals = new ArrayList<JSONObject>();
        for (Attribute att : attributes) {
            ResAttrVal val = attributeService.getResAttrVal(id, att.getId().longValue());
            JSONObject json = new JSONObject();
            if (att.getDataUnit() != null) {
                json.element("name", att.getName() + " (" + att.getDataUnit() + ")");
            } else {
                json.element("name", att.getName());
            }

            json.element("val", val == null ? "" : val.getAttrValue() == null ? "" : val.getAttrValue().trim());
            attVals.add(json);
        }

        results.add(attVals);
        List<ResBean> parents = RelationHelper.parents(id);
        if (parents.size() > 0) {
            ResBean pbean = parents.get(0);
            results.add(pbean.res());
        } else {
            results.add(null);
        }
        //资源指标
        Probe probe = probeService.findById(bean.res().getProbeId());
        results.add(probe);

        Struts2Utils.renderJson(results);
        return null;
    }

    /**
     * 数据格式：
     *     资源类别A
     *        资源A  资源B
     *     资源类别B
     *        资源C  资源D
     * @param parentResId
     */
    @SuppressWarnings("unused")
    public String children() {
        Long parentResId = Long.parseLong(Struts2Utils.getParameter("parentResId"));
        List<ResBean> children = RelationHelper.children(parentResId);
        List<List<ResBean>> types = new ArrayList<List<ResBean>>();
        for (ResBean child : children) {
            List<ResBean> type = null;
            for (int j = 0; j < types.size(); j++) {
                if (types.get(j).get(0).res().getResTypeId().longValue() == child.res().getResTypeId().longValue()) {
                    type = types.get(j);
                    break;
                }
            }
            if (type == null) {
                type = new ArrayList<ResBean>();
                types.add(type);
            }
            type.add(child);
        }
        //排序 按子资源多到少
        int loopNumber = types.size();
        for (int i = 0; i < loopNumber - 1; i++) {
            for (int c = 0; c < loopNumber - 1 - i; c++) {
                List<ResBean> prevBean = types.get(c);
                List<ResBean> compareBean = types.get(c + 1);
                if (prevBean.size() < compareBean.size()) {
                    types.set(c, compareBean);
                    types.set(c + 1, prevBean);
                }
            }
        }
        JSONArray childs = new JSONArray();
        for (List<ResBean> resBeans : types) {
            Res res = resBeans.get(0).res();
            ResType resType = ResTypeBean.get(res.getResTypeId()).resType();
            JSONObject child = new JSONObject();
            child.element("resTypeName", resType.getName());
            List<Res> listRes = new ArrayList<Res>();
            for (int i = 0; i < resBeans.size(); i++) {
                listRes.add(resBeans.get(i).res());
            }
            child.element("childNodes", listRes);
            childs.add(child);
        }
        Struts2Utils.renderJson(childs);
        return null;
    }

    /* (non-Javadoc)
     * @see com.opensymphony.xwork2.ModelDriven#getModel()
     */
    @Override
    public Res getModel() {
        // TODO Auto-generated method stub
        return entity;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @SuppressWarnings("rawtypes")
    class ProbeSort implements Comparator {
        @Override
        public int compare(Object obj1, Object obj2) {
            Probe res1 = (Probe) obj1;
            Probe res2 = (Probe) obj2;
            if (Math.abs(res1.getStatus() - 3) > Math.abs(res2.getStatus() - 3)) {
                return 1;
            } else {
                return 0;
            }
        }
    }

}
